package com.demo2do.fms.queue.service.impl;

import java.math.BigDecimal;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.fms.entity.business.balance.OtherFee;
import com.demo2do.fms.entity.business.shipment.DispatchOrder;
import com.demo2do.fms.entity.business.shipment.TransportCost;
import com.demo2do.fms.entity.data.business.OtherFeeType;
import com.demo2do.fms.entity.vam.OperationType;
import com.demo2do.fms.entity.vam.RemoteDispatchOrder;
import com.demo2do.fms.entity.vehicle.source.Vehicle;
import com.demo2do.fms.entity.vehicle.tractor.Tractor;
import com.demo2do.fms.queue.dao.TractorDao;
import com.demo2do.fms.queue.dao.order.OtherFeeDaoSupport;
import com.demo2do.fms.queue.dao.order.OtherFeeTypeDao;
import com.demo2do.fms.queue.dao.order.RemoteDispatchOrderDao;
import com.demo2do.fms.queue.dao.order.TransportCostDao;
import com.demo2do.fms.queue.entity.DispatchOrderStat;
import com.demo2do.fms.queue.service.RemoteDispatchOrderService;

/**
 *
 * @author Ark
 *
 */
@Service("remoteDispatchOrderService")
public class RemoteDispatchOrderServiceImpl implements RemoteDispatchOrderService {

    private static final Logger logger = LoggerFactory.getLogger(RemoteDispatchOrderServiceImpl.class);
    
    @Dao
    private RemoteDispatchOrderDao remoteDispatchOrderDao;
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Dao
    private OtherFeeTypeDao otherFeeTypeDao;
    
    @Autowired
    private OtherFeeDaoSupport otherFeeDaoSupport;
    
    @Dao
    private TransportCostDao transportCostDao;
    
    @Dao
    private TractorDao tractorDao;
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.queue.service.RemoteDispatchOrderService#finish()
     */
    public void finish() {
        
        List<RemoteDispatchOrder> remoteDispatchOrders = remoteDispatchOrderDao.list(OperationType.CREATE);
        if (CollectionUtils.isEmpty(remoteDispatchOrders)) {
            return;
        }
        
        for (RemoteDispatchOrder remoteDispatchOrder : remoteDispatchOrders) {
            
            try {
                
                DispatchOrder dispatchOrder = genericDaoSupport.load(DispatchOrder.class, remoteDispatchOrder.getDispatchOrderId());
                
                // 车辆信息
                Vehicle vehicle = genericDaoSupport.load(Vehicle.class, dispatchOrder.getVehicleId());
                Tractor tractor = tractorDao.getByBrandCNCode(vehicle.getBrandCNCode());
                if (tractor == null) {
                    throw BusinessException.newInstance("500", "车辆不存在");
                }
                
                // 罚款费用
                OtherFeeType otherFeeType = otherFeeTypeDao.load("其他费用");
                BigDecimal fineFee = BigDecimal.ZERO;
                OtherFee otherFeeTotal = otherFeeDaoSupport.load(otherFeeType.getId(), dispatchOrder.getId(), false);
                if (otherFeeTotal != null) {
                    fineFee = otherFeeTotal.getOtherFee();
                }
                
                // 派车单其他费用
                BigDecimal otherFeeSum = (BigDecimal) otherFeeDaoSupport.getOtherFee(dispatchOrder.getId());
                BigDecimal otherFee = BigDecimal.ZERO;
                if (otherFeeSum != null) {
                    otherFee = otherFeeSum.subtract(fineFee);
                }
                
                TransportCost transportCost = transportCostDao.load(dispatchOrder.getId());
                
                // 派车单统计信息
                DispatchOrderStat dispatchOrderStat = new DispatchOrderStat(dispatchOrder, transportCost, tractor, fineFee, otherFee);
                
                // 发送至消息队列
                String statJson = JsonUtils.toJson(dispatchOrderStat);
                byte[] messageBody = statJson.getBytes("UTF-8");

                Message message = MessageBuilder.withBody(messageBody)
                                                .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                                                .build();
                
                rabbitTemplate.setQueue("order-finish");
                rabbitTemplate.convertAndSend("direct-fms", "order-finish", message);
                
                // 处理成功
                genericDaoSupport.update(remoteDispatchOrder.success());
                
            } catch (Exception e) {
                genericDaoSupport.update(remoteDispatchOrder.fail(e.getMessage()));
                logger.error("#finish() - finish order[id={}] error, exception=[{}]", remoteDispatchOrder.getDispatchOrderId(), e);
            }
            
        }
        
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.queue.service.RemoteDispatchOrderService#edit()
     */
    public void edit() {

        List<RemoteDispatchOrder> remoteDispatchOrders = remoteDispatchOrderDao.list(OperationType.UPDATE);
        if (CollectionUtils.isEmpty(remoteDispatchOrders)) {
            return;
        }
        
        for (RemoteDispatchOrder remoteDispatchOrder : remoteDispatchOrders) {
            
            try {
                
                DispatchOrder dispatchOrder = genericDaoSupport.load(DispatchOrder.class, remoteDispatchOrder.getDispatchOrderId());
                
                // 车辆信息
                Vehicle vehicle = genericDaoSupport.load(Vehicle.class, dispatchOrder.getVehicleId());
                Tractor tractor = tractorDao.getByBrandCNCode(vehicle.getBrandCNCode());
                if (tractor == null) {
                    throw BusinessException.newInstance("500", "车辆不存在");
                }
                
                // 罚款费用
                OtherFeeType otherFeeType = otherFeeTypeDao.load("其他费用");
                BigDecimal fineFee = BigDecimal.ZERO;
                OtherFee otherFeeTotal = otherFeeDaoSupport.load(otherFeeType.getId(), dispatchOrder.getId(), false);
                if (otherFeeTotal != null) {
                    fineFee = otherFeeTotal.getOtherFee();
                }
                
                // 派车单其他费用
                BigDecimal otherFeeSum = (BigDecimal) otherFeeDaoSupport.getOtherFee(dispatchOrder.getId());
                BigDecimal otherFee = BigDecimal.ZERO;
                if (otherFeeSum != null) {
                    otherFee = otherFeeSum.subtract(fineFee);
                }
                
                TransportCost transportCost = transportCostDao.load(dispatchOrder.getId());
                
                // 派车单统计信息
                DispatchOrderStat dispatchOrderStat = new DispatchOrderStat(dispatchOrder, transportCost, tractor, fineFee, otherFee);
                
                // 发送至消息队列
                String statJson = JsonUtils.toJson(dispatchOrderStat);
                byte[] messageBody = statJson.getBytes("UTF-8");

                Message message = MessageBuilder.withBody(messageBody)
                                                .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                                                .build();
                
                rabbitTemplate.setQueue("order-edit");
                rabbitTemplate.convertAndSend("direct-fms", "order-edit", message);
                
                // 处理派车单
                genericDaoSupport.update(remoteDispatchOrder.success());
                
            } catch (Exception e) {
                genericDaoSupport.update(remoteDispatchOrder.fail(e.getMessage()));
                logger.error("#edit() - edit order[id={}] error, exception=[{}]", remoteDispatchOrder.getDispatchOrderId(), e);
            }
            
        }
        
    }

}
